package org.groupg.mockdatabyspring.morkdata.model.DBInfo;

import com.mifmif.common.regex.Generex;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.groupg.mockdatabyspring.morkdata.model.enums.ColumnType;

import java.io.Serializable;

/**
 * 字段对象
 *
 * @author ligengpu
 */
@Data

public class DBColumnInfo implements Serializable {

    /**
     * 表名
     */
    private String tableName;
    /**
     * 模式名
     */
    private String schemaName;
    /**
     * 用户名
     */
    private String username;
    /**
     * 字段名称
     */
    private String columnName;

    /**
     * 字段类型
     */
    private String columnType;
    /**
     * 是否主键
     */
    private boolean isPK;

    /**
     * 是否可为空
     */
    private boolean isNullAble;

    /**
     * 字段整数位的长度
     */
    private Integer dataMaxIntLength = 0;

    /**
     * 字段小数位的长度
     */
    private Integer dataDecimalLength = 0;

    /**
     * 用于创建内容的模板
     */
    private String strTmpId = "";

    /**
     * 字段说明
     */
    private String comment = "";

    /**
     * 数据来源字段
     */
    private DBColumnInfo fromColumnInfo = null;

    /**
     * 数据值
     */
    private String value = null;

    /**
     * 基础创建对象用构造函数
     *
     * @param tableName         表名
     * @param schemaName        模式名
     * @param username          用户名
     * @param columnName        字段名
     * @param columnType        字段类型 {@link ColumnType}
     * @param isPK              是否主键
     * @param isNullAble        是否可为空
     * @param dataMaxIntLength  字段最大长度
     * @param dataDecimalLength 小数位长度
     * @param strTmpId          字符串创建模板的内容或ID
     * @param comment           字段说明
     */
    public DBColumnInfo(@NotNull(message = "表名不能为空！") String tableName
            , @NotNull(message = "模式名不能为空！") String schemaName
            , @NotNull(message = "用户名不能为空！") String username
            , @NotNull(message = "字段名称不能为空！") String columnName
            , @NotNull(message = "字段类型不能为空！") String columnType
            , @NotNull(message = "是否主键不能为空！") boolean isPK
            , @NotNull(message = "【字段是否为空】不能为空！") boolean isNullAble
            , @NotNull(message = "字段整数长度不能为空！") Integer dataMaxIntLength
            , @NotNull(message = "字段小数长度不能为空！") Integer dataDecimalLength
            , @NotNull(message = "创建用正则不能为空") String strTmpId
            , String comment) {
        this.tableName = tableName;
        this.schemaName = schemaName;
        this.username = username;
        this.columnName = columnName;
        this.columnType = columnType;
        this.isPK = isPK;
        this.isNullAble = isNullAble;
        this.dataMaxIntLength = dataMaxIntLength;
        this.dataDecimalLength = dataDecimalLength;
        this.strTmpId = strTmpId;
        this.comment = comment;
    }

    /**
     * 构造数字类型字段的构造器
     *
     * @param tableName         表名
     * @param schemaName        模式名
     * @param username          用户名
     * @param columnName        字段名
     * @param isPK              是否主键
     * @param isNullAble        是否可为空
     * @param dataMaxIntLength  字段最大长度
     * @param dataDecimalLength 小数位长度
     * @param strTmpId          字符串创建模板的内容或ID
     * @param comment           字段说明
     * @return 生成的数字字段类型的列对象
     */
    public static DBColumnInfo createNumberColumn(String tableName
            , String schemaName
            , String username
            , String columnName
            , boolean isPK
            , boolean isNullAble
            , Integer dataMaxIntLength
            , Integer dataDecimalLength
            , String strTmpId
            , String comment) {
        return new DBColumnInfo(tableName, schemaName, username, columnName, ColumnType.INTEGER, isPK, isNullAble, dataMaxIntLength, dataDecimalLength, strTmpId, comment);
    }

    /**
     * 构造字符串类型字段的构造器
     *
     * @param tableName        表名
     * @param schemaName       模式名
     * @param username         用户名
     * @param columnName       字段名
     * @param isPK             是否主键
     * @param isNullAble       是否可为空
     * @param dataMaxIntLength 字段最大长度
     * @param strTmpId         字符串创建模板的内容或ID
     * @param comment          字段说明
     * @return 生成的字符串字段类型的列对象
     */
    public static DBColumnInfo createStringColumn(String tableName
            , String schemaName
            , String username
            , String columnName
            , boolean isPK
            , boolean isNullAble
            , Integer dataMaxIntLength
            , String strTmpId
            , String comment) {
        return new DBColumnInfo(tableName, schemaName, username, columnName, ColumnType.STRING, isPK, isNullAble, dataMaxIntLength, 0, strTmpId, comment);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;

        if (o == null || getClass() != o.getClass()) return false;

        DBColumnInfo that = (DBColumnInfo) o;

        return new EqualsBuilder().append(isPK(), that.isPK()).append(isNullAble(), that.isNullAble()).append(getTableName(), that.getTableName()).append(getSchemaName(), that.getSchemaName()).append(getUsername(), that.getUsername()).append(getColumnName(), that.getColumnName()).isEquals();
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder(17, 37).append(getTableName()).append(getSchemaName()).append(getUsername()).append(getColumnName()).toHashCode();
    }

    @Override
    public String toString() {
        return new ToStringBuilder(this)
                .append("tableName", tableName)
                .append("schemaName", schemaName)
                .append("username", username)
                .append("columnName", columnName)
                .append("columnType", columnType)
                .append("isPK", isPK)
                .append("isNullAble", isNullAble)
                .append("dataMaxIntLength", dataMaxIntLength)
                .append("dataDecimalLength", dataDecimalLength)
                .append("comment", comment)
                .toString();
    }

    /**
     * 根据当前对象的正则模板获取满足正则的示例内容。
     *
     * @return 根据正则生成的对象
     */
    public String getRandomString() {
        Generex generex = new Generex(this.getStrTmpId());
        if (this.getValue() == null ){
            this.setValue(generex.random());
        }
        return generex.random();
    }

    /**
     * 根据当前对象的正则模板获取满足正则的示例内容。
     *
     * @return 获取的上游字段对象，若上游字段对象为空，则返回当前正则造数据
     */
    public String getFromColumnValue() {
        if (this.getFromColumnInfo() == null){
            return this.getRandomString();
        }
        return this.getFromColumnInfo().getValue();
    }

}
